#ifndef __INTERNAL_H__
#define __INTERNAL_H__
#include <nfc/nfc.h>

#define MAX_CANDIDATES 16
#define MAX_CRYPTO_BLOCK_SIZE 16

#define ATQA_CLASSIC1K 	0x0004
#define ATQA_ULTRALIGHT 0X0044
#define ATQA_DESFIRE	0X0344

#define KEY_LENGTH_BYTES	16
static const char EMPTY_KEY[] = "Empty00000000000";
#define MAX_NUM_LOCKERS 2
#define KEY_SIZE 16
#define ERROR_RED_LED_BLINK_RATE 200
#define ERROR_RED_LED_BLINK_CYCLES 4


// commands
#define CMD_SELECT_AID_SIZE_TX 17
#define CMD_SELECT_AID_SIZE_RX 18
#define CMD_SEND_KEY_SIZE 20
#define CMD_SIZE_TX 4
#define CMD_SIZE_RX 2
#define CMD_SELECT_AID 	0x00A40400
#define CMD_SEND_KEY	0x00DA014B
#define CMD_ERROR_0		0x00DA01E0
#define CMD_ERROR_1		0x00DA01E1
#define CMD_DELETE_KEY	0x00DA014F

/* Status and error codes */

#define	OPERATION_OK		0x00
#define	NO_CHANGES		0x0C
#define	OUT_OF_EEPROM_ERROR	0x0E
#define	ILLEGAL_COMMAND_CODE	0x1C
#define	INTEGRITY_ERROR		0x1E
#define	NO_SUCH_KEY		0x40
#define	LENGTH_ERROR		0x7E
#define	PERMISSION_ERROR	0x9D
#define	PARAMETER_ERROR		0x9E
#define	APPLICATION_NOT_FOUND	0xA0
#define	APPL_INTEGRITY_ERROR	0xA1
#define	AUTHENTICATION_ERROR	0xAE
#define	ADDITIONAL_FRAME	0xAF
#define	BOUNDARY_ERROR		0xBE
#define	PICC_INTEGRITY_ERROR	0xC1
#define	COMMAND_ABORTED		0xCA
#define	PICC_DISABLED_ERROR	0xCD
#define	COUNT_ERROR		0xCE
#define	DUPLICATE_ERROR		0xDE
#define	EEPROM_ERROR		0xEE
#define	FILE_NOT_FOUND		0xF0
#define	FILE_INTEGRITY_ERROR	0xF1

#define NOT_YET_AUTHENTICATED 255

struct mifare_tag {
    nfc_device *device;
    nfc_iso14443a_info info;
    const struct supported_tag *tag_info;
    //int active;
};

enum mifare_tag_type {
    ULTRALIGHT,
    ULTRALIGHT_C,
//    MINI,
    CLASSIC_1K,
    CLASSIC_4K,
//    PLUS_S2K,
//    PLUS_S4K,
//    PLUS_X2K,
//    PLUS_X4K,
    DESFIRE
};

struct supported_tag {
    enum mifare_tag_type type;
    const char *friendly_name;
    uint8_t SAK;
    uint8_t ATS_min_length;
    uint8_t ATS_compare_length;
    uint8_t ATS[5];
    bool (*check_tag_on_reader) (nfc_device *, nfc_iso14443a_info);
};

enum desfire_cmd {
    SEND_KEY    = 0x4B,
    ERROR0      = 0xE0,
    ERROR1      = 0xE1,
    DELETE_KEY  = 0x4F
};

// macros
/*
 * Initialise a buffer named buffer_name of size bytes.
 */
#define BUFFER_INIT(buffer_name, size) \
    uint8_t buffer_name[size]; \
    size_t __##buffer_name##_size = size; \
    size_t __##buffer_name##_n = 0

/*
 * Append one byte of data to the buffer buffer_name.
 */
#define BUFFER_APPEND(buffer_name, data) \
    do { \
	buffer_name[__##buffer_name##_n++] = data; \
    } while (0)

/*
 * Append size bytes of data to the buffer buffer_name.
 */
#define BUFFER_APPEND_BYTES(buffer_name, data, size) \
    do { \
	size_t __n = 0; \
	while (__n < size) { \
	    buffer_name[__##buffer_name##_n++] = ((uint8_t *)data)[__n++]; \
	} \
    } while (0)

#define BUFFER_SIZE(buffer_name) (__##buffer_name##_n)

#define BUFFER_MAXSIZE(buffer_name) (__##buffer_name##_size)

#endif /* !__INTERNAL_H__ */
